import React, { useRef, useState } from 'react';
import { downloadUtils } from '@/utils';
import { useNavigate } from 'react-router-dom';

import {
  DeleteOutlined,
  DownloadOutlined,
  LinkOutlined,
  PlusOutlined,
  ReloadOutlined,
  SettingOutlined,
} from '@ant-design/icons';

import {
  type DeviceItem,
  deviceManagerListApi,
  deviceManagerRemoveApi,
  deviceManagerBatchRemoveApi,
  deviceManagerSaveOrUpdateApi,
  deviceManagerImportByProductCodeApi,
  deviceManagerDetailApi,
  deviceManagerChildDeviceByGateway,
  deviceManagerUnBindingGateWayDevice,
  deviceExport,
} from '@/api/deviceManagerApi';
import type { OperationType } from '@/constants';
import {
  OperationTypeList,
  ProductNodeType,
  getEnumItem,
  typeToValueEnum,
  DeviceListStatus,
  DeviceCreateTypeList,
} from '@/constants';
import { TableLocalePresets } from '@/utils/tableUtils';

import BindGatewayModal from './modules/BindGatewayModal';

import type { DeviceAddFormRef } from './modules/add';
import type { ActionType, ProColumns } from '@ant-design/pro-components';

// 动态导入组件
const DeviceAddForm = React.lazy(() => import('./modules/add'));

/**
 * 设备管理页面组件
 * 提供设备的创建、编辑、删除、绑定网关等功能，支持批量操作和数据导出
 */
const DeviceManager = () => {
  // 路由导航
  const navigate = useNavigate();

  // 表格操作引用
  const actionRef = useRef<ActionType>(null);

  // 设备添加表单引用
  const deviceAddRef = useRef<DeviceAddFormRef>(null);

  // 表单实例
  const [form] = AForm.useForm();

  // 抽屉状态管理
  const [drawerShow, setDrawerShow] = useState(false);
  const [drawerType, setDrawerType] = useState<OperationType>('ADD');
  const [currentRecord, setCurrentRecord] = useState<Partial<DeviceItem>>({});

  // 表格选择状态
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [selectedRows, setSelectedRows] = useState<DeviceItem[]>([]);

  // 绑定网关弹窗状态
  const [bindGatewayVisible, setBindGatewayVisible] = useState(false);

  // 加载状态
  const [_loading, _setLoading] = useState(false);

  // 设备模式状态：1-设备模式，2-网关模式
  const [deviceMode, setDeviceMode] = useState<1 | 2>(1);

  // 网关子设备抽屉状态
  const [gatewayDrawerVisible, setGatewayDrawerVisible] = useState(false);
  const [selectedGateway, setSelectedGateway] = useState<DeviceItem | null>(null);
  const [gatewayChildren, setGatewayChildren] = useState<DeviceItem[]>([]);
  const [childrenLoading, setChildrenLoading] = useState(false);
  const [exportParams, setExportParams] = useState<Record<string, unknown>>({});

  /**
   * 获取设备列表数据
   * @param params 查询参数
   * @returns 格式化的表格数据
   */
  const fetchData = async (params: Record<string, unknown>) => {
    try {
      // 处理分页参数
      const requestParams = {
        ...params,
        page: params.current,
        size: params.pageSize,
        // 设备模式下不传 nodeType，网关模式下传 nodeType: 2
        ...(deviceMode === 2 ? { nodeType: 2 } : {}),
      };
      setExportParams(requestParams);

      const res = await deviceManagerListApi(requestParams);

      if (res.success && res.data) {
        return {
          success: true,
          data: res.data.records ?? [],
          total: res.data.total ?? 0,
        };
      } else {
        window.$message.error(res.message || '获取设备列表失败');
        return {
          success: false,
          data: [],
          total: 0,
        };
      }
    } catch (error) {
      console.error('获取设备列表失败:', error);
      window.$message.error('获取设备列表失败，请稍后重试');
      return {
        success: false,
        data: [],
        total: 0,
      };
    }
  };
  /**
   * 删除单个设备
   * @param record 设备记录
   */
  const handleDelete = async (record: DeviceItem) => {
    // 参数验证
    if (!record || !record.id) {
      window.$message.error('删除失败：设备ID不存在');
      return;
    }

    const deviceName = record.code || record.deviceName || '未知设备';

    AModal.confirm({
      title: '确认删除',
      content: `确定要删除设备"${deviceName}"吗？删除后不可恢复。`,
      okText: '确定',
      cancelText: '取消',
      okType: 'danger',
      onOk: async () => {
        try {
          const res = await deviceManagerRemoveApi({ id: record.id! });
          if (res.success) {
            window.$message.success('设备删除成功');
            actionRef.current?.reload();

            // 如果删除的设备在选中列表中，需要更新选中状态
            if (record.id && selectedRowKeys.includes(record.id)) {
              const newSelectedKeys = selectedRowKeys.filter(key => key !== record.id!);
              const newSelectedRows = selectedRows.filter(row => row.id !== record.id!);
              setSelectedRowKeys(newSelectedKeys);
              setSelectedRows(newSelectedRows);
            }
          } else {
            window.$message.error(res.message || '删除失败');
          }
        } catch (error) {
          console.error('删除设备失败:', error);
          window.$message.error('删除失败，请重试');
        }
      },
    });
  };

  /**
   * 处理绑定网关操作
   * 只有子设备可以绑定网关
   */
  const handleBindGateway = () => {
    // 检查是否有选中的设备
    if (selectedRowKeys.length === 0) {
      window.$message.warning('请先选择要绑定的设备');
      return;
    }

    // 过滤出子设备
    const selectedSubDevices = selectedRows.filter(
      device => device.nodeType === ProductNodeType.SUB_DEVICE.value
    );

    // 验证选中的设备类型
    if (selectedSubDevices.length === 0) {
      window.$message.warning('只能为子设备绑定网关，请选择子设备');
      return;
    }

    if (selectedSubDevices.length !== selectedRows.length) {
      const nonSubDeviceCount = selectedRows.length - selectedSubDevices.length;
      window.$message.warning(
        `选中的设备中包含 ${nonSubDeviceCount} 个非子设备，只能为子设备绑定网关`
      );
      return;
    }

    // 打开绑定网关弹窗
    setBindGatewayVisible(true);
  };

  /**
   * 绑定网关成功回调
   * 清空选中状态并刷新列表
   */
  const handleBindGatewaySuccess = () => {
    setSelectedRowKeys([]);
    setSelectedRows([]);
    actionRef.current?.reload();
    window.$message.success('网关绑定成功');
  };

  /**
   * 批量删除设备
   */
  const handleBatchDelete = () => {
    if (selectedRowKeys.length === 0) {
      window.$message.warning('请先选择要删除的设备');
      return;
    }

    // 获取有效的设备ID
    const validIds = selectedRowKeys
      .map(key => Number(key))
      .filter((id): id is number => !isNaN(id) && id > 0);

    if (validIds.length === 0) {
      window.$message.error('选中的设备ID无效');
      return;
    }

    AModal.confirm({
      title: '确认批量删除',
      content: `确定要删除选中的${validIds.length}个设备吗？删除后不可恢复。请先确保设备没有分组`,
      okText: '确定删除',
      cancelText: '取消',
      okType: 'danger',
      onOk: async () => {
        try {
          const res = await deviceManagerBatchRemoveApi({ ids: validIds });
          if (res.success) {
            window.$message.success(`成功删除 ${validIds.length} 个设备`);
            // 清空选中状态
            setSelectedRowKeys([]);
            setSelectedRows([]);
            // 刷新列表
            actionRef.current?.reload();
          } else {
            window.$message.error(res.message || '批量删除失败');
          }
        } catch (error) {
          console.error('批量删除设备失败:', error);
          window.$message.error('批量删除失败，请重试');
        }
      },
    });
  };

  /**
   * 导出设备数据
   * TODO: 实现设备数据导出功能
   */
  const handleExportDevices = async () => {
    // window.$message.info('导出设备功能开发中，敬请期待...');
    try {
      const response = await deviceExport({
        ...exportParams,
        ids: selectedRowKeys,
      });
      const res = response as Response;

      if (res.status === 200) {
        downloadUtils.downloadFromResponse(res, '设备列表.xlsx');
        window.$message.success('设备列表导出成功');
      } else {
        const resData = downloadUtils.deCodeArrayBuffer(res.blob());
        if (resData && resData.errorCode) {
          window.$message.error(resData.errorMsg || '导出失败');
        } else {
          window.$message.error('导出失败，请稍后重试');
        }
      }
    } catch (error) {
      console.error('导出设备列表失败:', error);
      window.$message.error('导出失败，请稍后重试');
    }
  };

  /**
   * 处理网关行点击事件
   * 获取网关下的子设备
   */
  const handleGatewayRowClick = async (record: DeviceItem) => {
    if (deviceMode !== 2 || record.nodeType !== 2) {
      return; // 只有在网关模式下且点击的是网关设备才处理
    }

    setSelectedGateway(record);
    setGatewayDrawerVisible(true);
    setChildrenLoading(true);
    console.log('record', record);
    try {
      const res = await deviceManagerChildDeviceByGateway(
        record.productCode?.toString() || '',
        record.code || ''
      );

      if (res.success && res.data) {
        setGatewayChildren(Array.isArray(res.data) ? res.data : []);
      } else {
        window.$message.error(res.message || '获取网关子设备失败');
        setGatewayChildren([]);
      }
    } catch (error) {
      console.error('获取网关子设备失败:', error);
      window.$message.error('获取网关子设备失败，请稍后重试');
      setGatewayChildren([]);
    } finally {
      setChildrenLoading(false);
    }
  };

  /**
   * 解绑网关设备
   */
  const handleUnbindGatewayDevice = async (deviceId: string, deviceCode: string) => {
    AModal.confirm({
      title: '确认解绑',
      content: `确定要解绑设备"${deviceCode}"吗？解绑后该设备将从网关中移除。`,
      okText: '确定',
      cancelText: '取消',
      okType: 'danger',
      onOk: async () => {
        try {
          const res = await deviceManagerUnBindingGateWayDevice(deviceId);
          if (res.success) {
            window.$message.success('设备解绑成功');
            // 重新获取网关子设备列表
            if (selectedGateway) {
              handleGatewayRowClick(selectedGateway);
            }
          } else {
            window.$message.error(res.message || '设备解绑失败');
          }
        } catch (error) {
          console.error('设备解绑失败:', error);
          window.$message.error('设备解绑失败，请稍后重试');
        }
      },
    });
  };

  /**
   * 切换设备模式
   */
  const handleModeChange = (mode: 1 | 2) => {
    setDeviceMode(mode);
    // 切换模式后重新加载数据
    actionRef.current?.reload();
  };

  // 表格列定义
  const columns: ProColumns<DeviceItem>[] = [
    {
      title: '设备code',
      dataIndex: 'code',
      key: 'code',
      width: 160,
      search: true,
    },
    {
      title: '产品',
      dataIndex: 'productName',
      key: 'productName',
      width: 140,
      search: true,
    },
    {
      title: '设备状态',
      dataIndex: 'status',
      key: 'status',
      width: 100,
      search: true,
      valueEnum: typeToValueEnum(DeviceListStatus),
      render: (_, record) => {
        const activeItem = getEnumItem(DeviceListStatus, record.status as string);
        return <ABadge status={activeItem?.status as any} text={activeItem?.label || '未知'} />;
      },
    },
    {
      title: '节点类型',
      dataIndex: 'nodeType',
      key: 'nodeType',
      valueEnum: typeToValueEnum(ProductNodeType),
      width: 100,
      search: true,
    },
    {
      title: '创建方式',
      dataIndex: 'source',
      key: 'source',
      width: 100,
      valueEnum: typeToValueEnum(DeviceCreateTypeList),
      search: true,
    },
    {
      title: '添加时间',
      dataIndex: 'createTime',
      key: 'createTime',
      width: 180,
      search: false,
    },
    {
      title: '最近在线时间',
      dataIndex: 'latestOnlineTime',
      key: 'latestOnlineTime',
      width: 180,
      search: false,
    },
    {
      title: '操作',
      key: 'action',
      width: 180,
      fixed: 'right',
      search: false,
      render: (_, record) => (
        <ASpace size="small">
          <AButton
            type="link"
            size="small"
            onClick={() => navigate(`/device/list/detail/${record.id}`)}
          >
            详情
          </AButton>
          <AButton
            type="link"
            size="small"
            onClick={async () => {
              if (!record.id) {
                window.$message.error('设备ID不存在，无法编辑');
                return;
              }

              try {
                const res = await deviceManagerDetailApi({ id: record.id });
                if (res.success && res.data) {
                  handleEdit({
                    ...record,
                    ...res.data,
                  });
                } else {
                  window.$message.error(res.message || '获取设备详情失败');
                }
              } catch (error) {
                console.error('获取设备详情失败:', error);
                window.$message.error('获取设备详情失败，请稍后重试');
              }
            }}
          >
            编辑
          </AButton>
          <AButton type="link" size="small" danger onClick={() => handleDelete(record)}>
            删除
          </AButton>
        </ASpace>
      ),
    },
  ];

  /**
   * 打开新增设备抽屉
   */
  const handleAdd = () => {
    setDrawerType('ADD');
    setCurrentRecord({});
    setDrawerShow(true);
  };

  /**
   * 关闭抽屉并重置状态
   */
  const handleDrawerClose = () => {
    setCurrentRecord({});
    setDrawerType('ADD');
    setDrawerShow(false);
    form.resetFields(); // 关闭时重置表单
  };

  /**
   * 打开编辑设备抽屉
   * @param record 设备记录
   */
  const handleEdit = (record: Partial<DeviceItem>) => {
    if (!record.id) {
      window.$message.error('设备ID不存在，无法编辑');
      return;
    }

    setCurrentRecord(record);
    setDrawerType('EDIT');
    setDrawerShow(true);

    // 预填充表单数据
    setTimeout(() => {
      form.setFieldsValue({
        ...record,
        // 如果有城市数据，需要特殊处理
        cityValue:
          record.provinceName && record.cityName
            ? {
                province: record.provinceName,
                city: record.cityName,
              }
            : undefined,
      });
    }, 100); // 延迟一点确保表单已渲染
  };
  /**
   * 处理表单提交
   * 支持单个设备添加/编辑和批量导入
   */
  const handleSubmit = async () => {
    try {
      // 获取当前Tab类型和上传文件（编辑模式时activeTab默认为'single'）
      const activeTab =
        drawerType === 'EDIT' ? 'single' : deviceAddRef.current?.getActiveTab?.() || 'single';
      const uploadFile = deviceAddRef.current?.getUploadFile?.();

      if (activeTab === 'single') {
        // 单个添加/编辑：调用 deviceManagerSaveOrUpdateApi
        const params = await form.validateFields();
        const requestParams = {
          ...currentRecord,
          ...params,
        };

        const res = await deviceManagerSaveOrUpdateApi(requestParams);
        if (res.success) {
          form.resetFields();
          handleDrawerClose();
          const successMessage = drawerType === 'EDIT' ? '设备更新成功' : '设备创建成功';
          window.$message.success(successMessage);
          actionRef.current?.reload();
        } else {
          const errorMessage = drawerType === 'EDIT' ? '设备更新失败' : '设备创建失败';
          window.$message.error(res.message || errorMessage);
        }
      } else if (activeTab === 'batch') {
        // 批量添加：调用 deviceManagerImportByProductCodeApi
        if (!uploadFile) {
          window.$message.error('请先上传Excel文件');
          return;
        }

        const productCode = form.getFieldValue('productCode');
        if (!productCode) {
          window.$message.error('请选择所属产品');
          return;
        }

        const formData = new FormData();
        formData.append('excelfile', uploadFile);

        const res = await deviceManagerImportByProductCodeApi(formData, productCode);

        if (res.success) {
          handleDrawerClose();
          window.$message.success(
            `批量导入成功，共导入 ${(res.data as any)?.successCount || 0} 个设备`
          );
          actionRef.current?.reload();
        } else {
          window.$message.error(res.message || '批量导入失败');
        }
      }
    } catch (error) {
      console.error('提交失败:', error);
      if (error instanceof Error) {
        window.$message.error(`操作失败：${error.message}`);
      } else {
        window.$message.error('操作失败，请重试');
      }
    }
  };
  return (
    <div className="page-wrapper">
      <ADrawer
        destroyOnHidden
        title={`设备${OperationTypeList[drawerType].label}`}
        width={600}
        closable={{ 'aria-label': 'Close Button' }}
        footer={
          <ARow justify="end">
            <ASpace>
              <AButton
                onClick={() => {
                  setDrawerShow(false);
                }}
              >
                返回
              </AButton>
              {drawerType != 'DETAIL' && (
                <AButton type="primary" onClick={handleSubmit}>
                  提交
                </AButton>
              )}
            </ASpace>
          </ARow>
        }
        onClose={handleDrawerClose}
        open={drawerShow}
      >
        <div className="w-full px-8 py-8">
          <AForm form={form} layout="vertical" labelAlign="right" labelCol={{ span: 12 }}>
            <React.Suspense fallback={<ASpin />}>
              <DeviceAddForm
                ref={deviceAddRef}
                form={form}
                data={currentRecord as DeviceItem}
                mode={drawerType === 'EDIT' ? 'edit' : 'add'}
                onTabChange={tab => console.log('Tab changed to:', tab)}
                onFileChange={file => console.log('File changed:', file?.name)}
              />
            </React.Suspense>
          </AForm>
        </div>
      </ADrawer>
      <div className="page-title">
        <div className="page-main-title">设备管理</div>
        <div className="page-sub-title">
          设备管理提供设备的创建、编辑、删除、绑定网关等功能，支持批量操作和数据导出。
        </div>
      </div>
      <div className="page-content-box">
        <div className="page-content flex show-bg">
          <div className="w-full">
            <PProTable<DeviceItem>
              className="mh-table"
              actionRef={actionRef}
              columns={columns}
              request={fetchData}
              rowKey="id"
              onRow={record => ({
                onClick: () => handleGatewayRowClick(record),
                style: deviceMode === 2 && record.nodeType === 2 ? { cursor: 'pointer' } : {},
              })}
              search={{
                span: 6,
                labelWidth: 'auto',
                defaultCollapsed: false,
              }}
              pagination={{
                defaultPageSize: 10,
                showSizeChanger: true,
                showQuickJumper: true,
                showTotal: (total, range) =>
                  `共 ${total} 项数据，当前显示第 ${range[0]}-${range[1]} 项`,
              }}
              scroll={{ x: 1000 }}
              size="small"
              options={{
                density: false,
                reloadIcon: (
                  <AButton icon={<ReloadOutlined />} key="reload">
                    刷新
                  </AButton>
                ),
                setting: {
                  draggable: true,
                  checkable: true,
                  showListItemOption: true,
                  settingIcon: <AButton icon={<SettingOutlined />}>设置</AButton>,
                  listsHeight: 400,
                },
              }}
              toolBarRender={() => [
                <AButton.Group key="mode-switch">
                  <AButton
                    type={deviceMode === 1 ? 'primary' : 'default'}
                    onClick={() => handleModeChange(1)}
                  >
                    设备模式
                  </AButton>
                  <AButton
                    type={deviceMode === 2 ? 'primary' : 'default'}
                    onClick={() => handleModeChange(2)}
                  >
                    网关模式
                  </AButton>
                </AButton.Group>,
                <AButton
                  key="add"
                  icon={<PlusOutlined />}
                  type="primary"
                  onClick={() => {
                    handleAdd();
                    // 设置默认值
                    setTimeout(() => {
                      form.setFieldsValue({
                        source: 0, // 默认创建方式
                      });
                    }, 100);
                  }}
                >
                  新增设备
                </AButton>,
                <AButton
                  disabled={selectedRowKeys.length === 0}
                  key="bind-gateway"
                  icon={<LinkOutlined />}
                  onClick={handleBindGateway}
                >
                  绑定网关{selectedRowKeys.length > 0 ? `(${selectedRowKeys.length})` : ''}
                </AButton>,
                <AButton
                  key="batch-delete"
                  icon={<DeleteOutlined />}
                  danger
                  onClick={handleBatchDelete}
                  disabled={selectedRowKeys.length === 0}
                >
                  批量删除{selectedRowKeys.length > 0 ? `(${selectedRowKeys.length})` : ''}
                </AButton>,
                <AButton key="export" icon={<DownloadOutlined />} onClick={handleExportDevices}>
                  导出设备
                </AButton>,
              ]}
              locale={TableLocalePresets.product(actionRef)}
              tableAlertRender={false} // 👈 彻底隐藏“已选择 X 项”提示
              tableAlertOptionRender={false} // 👈 隐藏“取消选择”等操作按钮
              rowSelection={{
                selectedRowKeys,
                onChange: (selectedRowKeys, selectedRows) => {
                  setSelectedRowKeys(selectedRowKeys);
                  setSelectedRows(selectedRows);
                },
                getCheckboxProps: record => ({
                  disabled: false,
                  name: record.code,
                }),
                // 隐藏选择操作按钮
                selections: false,
              }}
            />
          </div>
        </div>
      </div>

      {/* 绑定网关弹窗 */}
      <BindGatewayModal
        visible={bindGatewayVisible}
        selectedDevices={selectedRows}
        onCancel={() => setBindGatewayVisible(false)}
        onSuccess={handleBindGatewaySuccess}
      />

      {/* 网关子设备抽屉 */}
      <ADrawer
        title={`网关子设备 - ${selectedGateway?.code || ''}`}
        placement="right"
        width={1000}
        onClose={() => {
          setGatewayDrawerVisible(false);
          setSelectedGateway(null);
          setGatewayChildren([]);
        }}
        open={gatewayDrawerVisible}
      >
        <div style={{ marginBottom: '16px' }}>
          <ATag color="blue">网关名称: {selectedGateway?.code}</ATag>
          <ATag color="green">子设备数量: {gatewayChildren.length}</ATag>
        </div>

        <PProTable<DeviceItem>
          columns={[
            {
              title: '设备code',
              dataIndex: 'code',
              key: 'code',
              width: 160,
            },
            {
              title: '产品',
              dataIndex: 'productName',
              key: 'productName',
              width: 140,
            },
            {
              title: '设备状态',
              dataIndex: 'status',
              key: 'status',
              width: 100,
              valueEnum: typeToValueEnum(DeviceListStatus),
              render: (_, record) => {
                const activeItem = getEnumItem(DeviceListStatus, record.status as string);
                return (
                  <ABadge status={activeItem?.status as any} text={activeItem?.label || '未知'} />
                );
              },
            },
            {
              title: '创建方式',
              dataIndex: 'source',
              key: 'source',
              width: 100,
              valueEnum: typeToValueEnum(DeviceCreateTypeList),
            },
            {
              title: '添加时间',
              dataIndex: 'createTime',
              key: 'createTime',
              width: 180,
            },
            {
              title: '操作',
              key: 'action',
              width: 120,
              fixed: 'right',
              render: (_, record) => (
                <ASpace size="small">
                  <AButton
                    type="link"
                    size="small"
                    danger
                    onClick={() =>
                      handleUnbindGatewayDevice(record.id?.toString() || '', record.code || '')
                    }
                  >
                    解绑
                  </AButton>
                </ASpace>
              ),
            },
          ]}
          dataSource={gatewayChildren}
          loading={childrenLoading}
          rowKey="id"
          size="small"
          search={false}
          options={false}
          pagination={{
            total: gatewayChildren.length,
            pageSize: 10,
            showSizeChanger: true,
            showTotal: total => `共 ${total} 个子设备`,
          }}
        />
      </ADrawer>
    </div>
  );
};

export default DeviceManager;
